package com.pactera.widget;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;

import com.pactera.utils.HttpUtil;

/**
 * 下载任务
 * 
 * @author Administrator
 * 
 */
public class DownloadRunnable implements Runnable {

	// 请求对象
	private DownloadInfo dLoadInfo;
	private DownloadCallback dcb;
	private File _file;

	// 成功
	public static final int STATUS_SUCCESS = 0;
	// 失败
	public static final int STATUS_FAIL = 1;

	// 缓存
	private static final int MAX_BUFFER_SIZE = 1024;

	private int size; // 文件大小（byte）
	private int downloaded; // 已下载的文件大小

	public DownloadRunnable(DownloadInfo dLoadInfo, DownloadCallback dcb) {
		this.dLoadInfo = dLoadInfo;
		size = 0;
		this.downloaded = 0;
		this.dcb = dcb;
	}

	// 下载链接
	public String getUrl() {
		return dLoadInfo.getDownloadurl();
	}

	// 文件大小
	public int getSize() {
		return size;
	}

	public DownloadInfo getdReqInfo() {
		return dLoadInfo;
	}

	public void setSize(int size) {
		this.size = size;
	}

	@Override
	public void run() {
		/*
		 * RandomAccessFile是用来访问那些保存数据记录的文件的，你就可以用seek( )方法来访问记录，并进行读写了
		 * 这些记录的大小不必相同；但是其大小和位置必须是可知的。但是该类仅限于操作文件�?
		 */
		RandomAccessFile file = null;
		InputStream stream = null;
		try {
			HttpURLConnection connection = HttpUtil.getHttpURLConnection(
					dLoadInfo.getDownloadurl(), "GET",
					"application/x-www-form-urlencoded", "");
			connection.setInstanceFollowRedirects(false);
			// 支持断点续传
			connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
			_file = new File(dLoadInfo.getLocalpath() + "td");
			_file.createNewFile();
			file = new RandomAccessFile(dLoadInfo.getLocalpath() + "td", "rw");

			// 连接
			connection.connect();
			// 获得文件大小
			int contentLength = connection.getContentLength();
			if (file.length() == contentLength) {
				_file.renameTo(new File(dLoadInfo.getLocalpath()));
				dcb.callback(dLoadInfo, STATUS_SUCCESS);
				return;
			}
			if (contentLength == 0 || file.length() > 0) {
				// 删除文件
				if (_file.exists()) {
					_file.delete();
				}
				dcb.callback(dLoadInfo, STATUS_FAIL);
				return;
			}
			// 设置文件大小(如果没有设置过文件大小
			size = contentLength + downloaded;

			file.seek(downloaded);
			stream = connection.getInputStream();
			byte buffer[];
			while (true) {
				if (size - downloaded > MAX_BUFFER_SIZE) {
					buffer = new byte[MAX_BUFFER_SIZE];
				} else {
					buffer = new byte[size - downloaded];
				}
				int read = stream.read(buffer);
				if (read == -1)
					break;
				file.write(buffer, 0, read);
				downloaded += read;
			}
			// 下载完成
			_file.renameTo(new File(dLoadInfo.getLocalpath()));
			dcb.callback(dLoadInfo, STATUS_SUCCESS);
			return;
		} catch (Exception e) {
			e.printStackTrace();
			// 删除文件
			if (_file != null && _file.isFile() && _file.exists()) {
				_file.delete();
			}
			dcb.callback(dLoadInfo, STATUS_FAIL);
			return;
		} finally {
			if (file != null) {
				try {
					file.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (stream != null) {
				try {
					stream.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static interface DownloadCallback {
		public void callback(DownloadInfo dLoadInfo, int status);
	}
}
